#include <stdlib.h>

#include "base.h"
#include "timing.h"
#include "string.h"
#include "errno.h"
#include <assert.h>

static void timing_handler(int fd, short which, void * arg)
{
	TIMING * t = (TIMING *)arg;
	assert(t);

	if (t->ontiming(t->obj) < 0) {
		send_log(LV_ERROR, "#timing_handler# ontiming");
		return;
	}

	evtimer_del(&t->event);
	if (evtimer_add(&t->event, &t->interval) < 0) {
		send_log(LV_ERROR, "#timing_handler# evtimer_add"); 
		return ;
	}
}

TIMING * timing_new(unsigned int usec, ONTIMING_FUNC ontiming,
					struct event_base * base, const void * obj)
{
	if (!usec || !ontiming || !base) return NULL;

	TIMING * t = malloc(sizeof(struct TIMING));
	if (!t) {
		send_log(LV_FATAL, "#timing_new# malloc() %s", strerror(errno));
		return NULL;
	}

	t->interval.tv_sec = usec / 1000000;
	t->interval.tv_usec = usec % 1000000;

	t->ontiming = ontiming;
	t->base = base;
	t->obj = obj;

	evtimer_set(&t->event, timing_handler, (void *)t);
	event_base_set(t->base, &t->event);

	if (evtimer_add(&t->event, &t->interval) < 0) {
		send_log(LV_ERROR, "#timing_new# monitor libevent timer failed"); 
		free(t);
		return NULL;
	}
	return t;
}

int timing_free(TIMING * t)
{
	if (!t) return 1;

	evtimer_del(&t->event);
	free(t);
	return 0;
}

